home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Apache 1.0 / src / mod_imap.c < prev    next >
Text File  |  1995-12-04  |  12KB  |  457 lines

  1.  
  2. /* ====================================================================
  3.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the Apache Group
  20.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  21.  *
  22.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission.
  25.  *
  26.  * 5. Redistributions of any form whatsoever must retain the following
  27.  *    acknowledgment:
  28.  *    "This product includes software developed by the Apache Group
  29.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  30.  *
  31.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  32.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  35.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  42.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  * ====================================================================
  44.  *
  45.  * This software consists of voluntary contributions made by many
  46.  * individuals on behalf of the Apache Group and was originally based
  47.  * on public domain software written at the National Center for
  48.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  49.  * For more information on the Apache Group and the Apache HTTP server
  50.  * project, please see <http://www.apache.org/>.
  51.  *
  52.  */
  53.  
  54.  
  55. /*
  56.  * This imagemap module is essentially a port of the original imagemap.c
  57.  * written by Rob McCool (11/13/93 robm@ncsa.uiuc.edu).
  58.  * This version includes the mapping algorithms found in version 1.3
  59.  * of imagemap.c.
  60.  *
  61.  * Contributors to this code include:
  62.  *
  63.  * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu
  64.  *
  65.  * Eric Haines, erich@eye.com
  66.  * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
  67.  *
  68.  * Randy Terbush, randy@zyzzyva.com
  69.  * port to Apache module format, "base_uri" and support for relative URLs
  70.  * 
  71.  * James H. Cloos, Jr., cloos@jhcloos.com
  72.  * Added point datatype, using code in NCSA's version 1.8 imagemap.c
  73.  * program, as distributed with version 1.4.1 of their server.
  74.  * The point code is originally added by Craig Milo Rogers, Rogers@ISI.Edu
  75.  *
  76.  */
  77.  
  78.  
  79. #include "httpd.h"
  80. #include "http_config.h"
  81. #include "http_request.h"
  82. #include "http_core.h"
  83. #include "http_protocol.h"
  84. #include "http_main.h"
  85. #include "http_log.h"
  86. #include "util_script.h"
  87.  
  88. #define IMAP_MAGIC_TYPE "application/x-httpd-imap"
  89. #define MAXLINE 500
  90. #define MAXVERTS 100
  91. #define X 0
  92. #define Y 1
  93.  
  94. char *getline(char *, int, FILE *);
  95.  
  96. module imap_module;
  97.  
  98. int pointinrect(double point[2], double coords[MAXVERTS][2])
  99. {
  100.     return ((point[X] >= coords[0][X] && point[X] <= coords[1][X]) &&
  101.         (point[Y] >= coords[0][Y] && point[Y] <= coords[1][Y]));
  102. }
  103.  
  104. int pointincircle(double point[2], double coords[MAXVERTS][2])
  105. {
  106.     int radius1, radius2;
  107.  
  108.     radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
  109.     + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));
  110.     
  111.     radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
  112.     + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
  113.  
  114.     return (radius2 <= radius1);
  115. }
  116.  
  117. int pointinpoly(double point[2], double pgon[MAXVERTS][2])
  118. {
  119.     int i, numverts, inside_flag, xflag0;
  120.     int crossings;
  121.     double *p, *stop;
  122.     double tx, ty, y;
  123.  
  124.     for (i = 0; pgon[i][X] != -1 && i < MAXVERTS; i++);
  125.  
  126.     numverts = i;
  127.     crossings = 0;
  128.  
  129.     tx = point[X];
  130.     ty = point[Y];
  131.     y = pgon[numverts - 1][Y];
  132.  
  133.     p = (double *) pgon + 1;
  134.     if ((y >= ty) != (*p >= ty)) {
  135.  
  136.     if ((xflag0 = (pgon[numverts - 1][X] >= tx)) == (*(double *) pgon >= tx)) {
  137.         if (xflag0)
  138.         crossings++;
  139.     }
  140.     else {
  141.         crossings += (pgon[numverts - 1][X] - (y - ty) *
  142.               (*(double *) pgon - pgon[numverts - 1][X]) /
  143.               (*p - y)) >= tx;
  144.     }
  145.     }
  146.  
  147.     stop = pgon[numverts];
  148.  
  149.     for (y = *p, p += 2; p < stop; y = *p, p += 2) {
  150.     
  151.     if (y >= ty) {
  152.         
  153.         while ((p < stop) && (*p >= ty))
  154.         p += 2;
  155.         
  156.         if (p >= stop)
  157.         break;
  158.         if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
  159.         
  160.         if (xflag0)
  161.             crossings++;
  162.         }
  163.         else {
  164.         crossings += (*(p - 3) - (*(p - 2) - ty) *
  165.                   (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
  166.         }
  167.     }
  168.     else {
  169.         while ((p < stop) && (*p < ty))
  170.         p += 2;
  171.  
  172.         if (p >= stop)
  173.         break;
  174.  
  175.         if ((xflag0 = (*(p - 3) >= tx)) == (*(p - 1) >= tx)) {
  176.         if (xflag0)
  177.             crossings++;
  178.         }
  179.         else {
  180.         crossings += (*(p - 3) - (*(p - 2) - ty) *
  181.                   (*(p - 1) - *(p - 3)) / (*p - *(p - 2))) >= tx;
  182.         }
  183.     }
  184.     }
  185.  
  186.     inside_flag = crossings & 0x01;
  187.     return (inside_flag);
  188. }
  189.  
  190.  
  191. void set_redirect (request_rec *r, char *base_uri, char *mapurl) {
  192.  
  193.     char redirect[MAXLINE];
  194.     char rooturl[80];
  195.     char port[40];
  196.     char *basedir;
  197.     char *u,*b,*q;
  198.     int k;
  199.  
  200.     server_rec *s = r->server;
  201.  
  202.     if (s->port != 80) {
  203.  
  204.     sprintf (port, "%d", s->port);
  205.     sprintf (rooturl, "http://%s:%s", s->server_hostname, port);
  206.     }
  207.     else {
  208.  
  209.     sprintf (rooturl, "http://%s", s->server_hostname);
  210.     }
  211.  
  212.     if ((!strncmp (mapurl, "http:", 5 )) ||
  213.     !strncmp (mapurl, "mailto:", 7) ||
  214.     !strncmp (mapurl, "ftp:", 4) ||
  215.     !strncmp (mapurl, "telnet:", 7) ||
  216.     !strncmp (mapurl, "news:", 5)) {
  217.  
  218.     strcpy (redirect, mapurl);
  219.     }
  220.     else if (*base_uri)  {
  221.  
  222.     while ((u = strstr (mapurl, "..")) != NULL) {
  223.         
  224.         if ((k = strlen(u)) > 3) {
  225.         mapurl = u + 3;
  226.         }
  227.         else {
  228.         mapurl = u + k;
  229.         }
  230.         
  231.         b = strrchr (base_uri, '/');
  232.         *b = '\0';
  233.     }
  234.     
  235.     b = strrchr (base_uri, '/'); b++;
  236.     *b = '\0';
  237.  
  238.     sprintf (redirect, "%s%s", base_uri, mapurl);
  239.     }
  240.     else if (mapurl[0] == '/') {
  241.     
  242.     sprintf (redirect, "%s%s", rooturl, mapurl);
  243.     }
  244.     else {
  245.  
  246.     basedir = r->uri;
  247.  
  248.     q = strrchr (basedir, '/'); q++;
  249.     *q = '\0';
  250.  
  251.     sprintf (redirect, "%s%s%s", rooturl, basedir, mapurl);
  252.     }
  253.     
  254.     table_set (r->headers_out, "Location", redirect);
  255. }
  256.  
  257.  
  258. int imap_handler (request_rec *r)
  259. {
  260.  
  261.     char input[MAXLINE];
  262.     char mapdflt[MAXLINE];
  263.     char maptype[MAXLINE];
  264.     char mapurl[MAXLINE];
  265.     char base_uri[MAXLINE];
  266.     char num[10];
  267.     double testpoint[2], pointarray[MAXVERTS][2];
  268.     int i, j, k;
  269.     FILE *imap;
  270.     char *ycoord;
  271.     char *referer;
  272.     double dist = 0;
  273.     double mindist = 0;
  274.     int sawpoint = 0;
  275.  
  276.  
  277.     if (r->args == NULL) { /* Client doesn't support Imagemaps, */
  278.       testpoint[X] = -1;   /* so fake some co-ordinates so that */
  279.       testpoint[Y] = -1;   /* the default is picked.  MJC 02Nov95 */
  280.     } else {
  281.         if (!(ycoord = strchr (r->args, ',')))
  282.           return BAD_REQUEST;
  283.         *ycoord++ = '\0';
  284.         testpoint[X] = (double) atoi (r->args);
  285.         testpoint[Y] = (double) atoi (ycoord);
  286.     }
  287.       
  288.     if (!(imap = fopen (r->filename,"r")))
  289.         return SERVER_ERROR;
  290.     
  291.     referer = table_get (r->headers_in, "Referer");
  292.     base_uri[0] = '\0';
  293.  
  294.     while ((getline(input, MAXLINE, imap))) {
  295.  
  296.     if ((input[0] == '#') || (!input[0]) )
  297.         continue;
  298.  
  299.     maptype[0] = '\0';
  300.     mapurl[0] = '\0';
  301.  
  302.     for (i = 0; (isalpha(input[i]) || input[i] == '_') && input[i]; i++ )
  303.         maptype[i] = input[i];
  304.     maptype[i] = '\0';
  305.  
  306.     while (isspace(input[i])) ++i;
  307.  
  308.     for (j = 0; input[i] && !isspace(input[i]); ++i,++j)
  309.         mapurl[j] = input[i];
  310.     mapurl[j] = '\0';
  311.  
  312.     if (!strcmp (maptype, "base_uri")) {
  313.     
  314.         if (!strcmp (mapurl, "map")) {
  315.         
  316.         strcpy (base_uri, r->uri);
  317.         }
  318.         else if (!strcmp (mapurl, "referer")) {
  319.  
  320.         if (referer != NULL) {
  321.  
  322.             strcpy (base_uri, referer);
  323.         }
  324.         else {
  325.             strcpy (base_uri, r->uri);
  326.         }
  327.         }
  328.         else if ((mapurl[0] == '/') || (!strstr (mapurl, "://")))  {
  329.         
  330.         strcpy (base_uri, mapurl);
  331.         }
  332.  
  333.         k = strlen (base_uri);
  334.         base_uri[k] = '\0';
  335.         continue;
  336.     }
  337.  
  338.         if (!strcmp (maptype, "default")) {
  339.  
  340.             strcpy (mapdflt, mapurl);
  341.             continue;
  342.         }
  343.  
  344.         k = 0;
  345.         while (input[i]) {
  346.  
  347.             while (isspace(input[i]) || input[i] == ',') i++;
  348.  
  349.             j = 0;
  350.  
  351.             while (isdigit(input[i]))
  352.                 num[j++] = input[i++];
  353.  
  354.             num[j] = '\0';
  355.  
  356.             if (num[0] != '\0') {
  357.  
  358.         pointarray[k][X] = (double) atoi(num);
  359.         }
  360.             else
  361.                 break;
  362.  
  363.             while (isspace(input[i]) || input[i] == ',') i++;
  364.  
  365.             j = 0;
  366.  
  367.             while (isdigit(input[i]))
  368.                 num[j++] = input[i++];
  369.  
  370.             num[j] = '\0';
  371.  
  372.             if (num[0] != '\0') {
  373.                 pointarray[k++][Y] = (double) atoi (num);
  374.         }
  375.             else {
  376.                 fclose (imap);
  377.                 return SERVER_ERROR;
  378.             }
  379.         }
  380.  
  381.         pointarray[k][X] = -1;
  382.         
  383.     if (!strcmp (maptype,"poly")) {
  384.             
  385.         if (pointinpoly (testpoint,pointarray)) {
  386.         set_redirect (r, base_uri, mapurl);
  387.             fclose (imap);
  388.         return REDIRECT;
  389.         }
  390.     }
  391.  
  392.         if (!strcmp (maptype,"circle")) {
  393.  
  394.             if(pointincircle (testpoint,pointarray)) {
  395.         set_redirect (r, base_uri, mapurl);
  396.             fclose (imap);
  397.         return REDIRECT;
  398.         }
  399.     }
  400.  
  401.         if (!strcmp (maptype,"rect")) {
  402.  
  403.             if (pointinrect (testpoint,pointarray)) {
  404.         set_redirect (r, base_uri, mapurl);
  405.             fclose (imap);
  406.         return REDIRECT;
  407.         }
  408.     }
  409.     if (!strcmp (maptype,"point")) {
  410.         /* Don't need to take sqaure root */
  411.         dist = ((testpoint[X] - pointarray[0][X])
  412.          *  (testpoint[X] - pointarray[0][X]))
  413.              + ((testpoint[Y] - pointarray[0][Y])
  414.          *  (testpoint[Y] - pointarray[0][Y]));
  415.         /* If this is the first point, or the nearest, set the default. */
  416.         if ((! sawpoint) || (dist < mindist)) {
  417.              mindist = dist;
  418.              strcpy(mapdflt,mapurl);
  419.         }
  420.         sawpoint++;
  421.     }
  422.     }
  423.  
  424.     if (mapdflt[0]) {
  425.  
  426.     set_redirect (r, base_uri, mapdflt);
  427.         fclose(imap);
  428.     return REDIRECT;
  429.     }
  430.  
  431.     fclose (imap);
  432.     return SERVER_ERROR;
  433. }
  434.  
  435. handler_rec imap_handlers[] = {
  436. { IMAP_MAGIC_TYPE, imap_handler },
  437. { NULL }
  438. };
  439.  
  440. module imap_module = {
  441.    STANDARD_MODULE_STUFF,
  442.    NULL,            /* initializer */
  443.    NULL,            /* dir config creater */
  444.    NULL,            /* dir merger --- default is to override */
  445.    NULL,            /* server config */
  446.    NULL,            /* merge server config */
  447.    NULL,            /* command table */
  448.    imap_handlers,        /* handlers */
  449.    NULL,            /* filename translation */
  450.    NULL,            /* check_user_id */
  451.    NULL,            /* check auth */
  452.    NULL,            /* check access */
  453.    NULL,            /* type_checker */
  454.    NULL,            /* fixups */
  455.    NULL                /* logger */
  456. };
  457.